#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>

// 排序比较函数
int cmp(const void *p, const void *q);
// 输出重复数字
void print_repetition(int n);

int main()
{
    int i;
    int a[] = {282112, 2822, 1234, 112355, 12345678};

    for(i = 0; i < sizeof(a) / sizeof(a[0]); i++)
    {
        printf("%d: ", a[i]);
        print_repetition(a[i]);
    }

    return 0;
}

// 输出重复数字
void print_repetition(int n)
{
    char s[8] = {0};
    const char *p_str;
    size_t offset = 0;
    int flag = 0;
    // 声明struct re_pattern_buffer对象
    struct re_pattern_buffer pat_buf;
    // 记录匹配信息的结构体变量(匹配寄存器)
    struct re_registers regs;
    const char *err_code;
    int pos;

    // 正则表达式(注意用\\转义)
    const char pat[] = "([0-9])\\1+";

    // 判断整数有效性
    if(n <= 0 || n > 10000000)
    {
        printf("Invalid input\n");
        return;
    }

    if(n > 0 && n < 10)
    {
        printf("No repeated numbers.\n");
        return;
    }

    // 将整数转换为字符串并排序
    sprintf(s, "%d", n);
    qsort(s, strlen(s), 1, cmp);

    // 正则初始化
    memset(&pat_buf, 0, sizeof(struct re_pattern_buffer));

    re_set_syntax(RE_SYNTAX_EGREP);

    memset(&regs, 0, sizeof(struct re_registers));

    // 编译正则表达式
    err_code  = re_compile_pattern(pat, strlen(pat), &pat_buf);
    if(err_code != NULL)
    {
        printf("erro: %s\n", err_code);
        regfree(&pat_buf);
        exit(EXIT_FAILURE);
    }

    // 变量赋初值
    offset = 0;
    flag = 0;

    // 循环正则搜索
    do
    {
        // 字符串偏移
        p_str = s + offset;

        // 正则搜索
        pos = re_search(&pat_buf, p_str, strlen(p_str),
                        0, strlen(p_str), &regs);

        if(pos < 0) // 未找到，退出循环
        {
            break;
        }
        else
        {
            // 输出重复数字
            putchar(p_str[pos]);
            putchar(' ');

            // 置标志
            flag = 1;

            // 下一次查找开始位置
            offset += regs.end[0];
            continue;
        }
    }while(1);

    // 释放空间
    regfree(&pat_buf);
    // 匹配寄存器成员需要单独释放
    free(regs.start);
    free(regs.end);

    // 无重复数字
    if(!flag)
    {
        printf("No repeated numbers.\n");
    }
    else
    {
        printf("\n");
    }
}

int cmp(const void *p, const void *q)
{
    char ch_p = *((char*)p);
    char ch_q = *((char*)q);

    return (ch_p > ch_q) - (ch_p < ch_q);
}
